home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 23 / luu164.zip / LUU164.ASM
Assembly Source File  |  1989-03-20  |  24KB  |  1,080 lines

  1.     Page    80,132
  2.     Title    - LUU - Update LBR File
  3.  
  4.     Comment | Version 1.64, March 3, 1985
  5.  
  6. LUU Command
  7. -----------
  8.  
  9. Purpose:   Add or replace members in an LU or LAR type library.
  10.  
  11. Format:    LUU    [d:][path]filename[.ext] filename[.ext]
  12.  
  13. Remarks:   The library name and at input member file name must
  14.        be supplied. Only one member name is allowed, so far.
  15.  
  16. Notes:       Written for the IBM PC using DOS 2.0 or later.
  17.        Copyright 1984 Vernon Buerg, for public domain use.
  18.  
  19.        LUU duplicates the A(dd) and U(pdate) functions of LU.
  20.  
  21. ----------|
  22.  
  23. ;    Library directory entry description
  24.  
  25. DirNtry Struc                ;LU/LAR directory entries
  26. D_Stat    Db    0            ; File status
  27. D_File    Db    '        '              ; File name (FCB format)
  28. D_Ext    Db    '   '                   ; Extension part
  29. D_Ptr    Dw    0            ; Offset to data (mod 128)
  30. D_Len    Dw    0            ; Length, 128-byte sectors
  31.                     ; CP/M formatted fields
  32. D_CRC    Dw    0            ;  Cyclic Redundancy Check value
  33. D_Cdate Dw    0            ;  Create date
  34. D_Udate Dw    0            ;  Update date
  35. D_Ctime Dw    0            ;  Create time
  36.  
  37. D_Utime Dw    0            ;  Update time
  38. D_Pad    Dw    0,0,0            ;  Unused/reserved
  39. DirNtry Ends
  40.  
  41. ;    Equates
  42.  
  43. Active    Equ    0
  44. Deleted Equ    254
  45. Unused    Equ    255
  46.  
  47. Dir_Len Equ    Size DirNtry        ; Size of a directory entry
  48.  
  49. CR    Equ    13
  50. LF    Equ    10
  51. Stopper Equ    255            ; Ends a PrintS string
  52.  
  53. MaxDir    Equ    256            ; Maximum directory entries
  54. DirSize Equ    Dir_Len * MaxDir    ;  and total size
  55. BufSize Equ    12*1024         ; Minimum I/O buffer size
  56.  
  57. Dater    Record    Yr:7,Mo:4,Dy:5        ; Mask for DOS date
  58. Timer    Record    Hh:5,Mm:6,Xx:5        ;  and time
  59.     Page
  60.     ;
  61.     ;   Update an LBR Library file
  62.  
  63. Cseg    Segment Public Para 'CODE'
  64.     Assume    CS:Cseg,DS:Cseg,ES:Cseg,SS:Cseg
  65.     Org    100h
  66.  
  67. Luu    Proc    Far
  68.     Push    DS            ; Standard entry
  69.     Sub    AX,AX            ;  for DOS return
  70.     Push    AX
  71.     Mov    StkTop,SP
  72.  
  73.     Call    Alloc            ; Get buffers
  74.  
  75.     Call    GetParm         ; Get Library file name
  76.  
  77.     Call    OpenLbr         ; Open library
  78.  
  79.     Call    LoadDir         ; Load directory
  80.  
  81.     Call    Search            ; Add or replace member(s)
  82.  
  83.     Call    CloseLbr        ; Close the library
  84.  
  85. Done:    Mov    DX,Offset EofMsg    ; Say "Done"
  86.  
  87. Error:    Mov    SP,StkTop        ; Insure stack is proper
  88.     Call    PrintS            ; Display final message
  89.  
  90.     Ret                ; Return to DOS
  91.     Page
  92. ;
  93. ;    Load entire directory
  94.  
  95. LoadDir Proc    Near
  96.  
  97.     Cmp    NumDir,0        ;Already loaded by Create?
  98.     Je    Load1
  99.     Ret
  100.  
  101. Load1:    Mov    DX,MstPtr        ;Read master directory entry
  102.     Call    ReadLib         ; of one 32-byte sector
  103.  
  104.     Mov    BX,MstPtr
  105.     Cmp    Byte Ptr [BX].D_Stat,0    ;Active first entry?
  106.     Jne    NotLBR
  107.     Cmp    Byte Ptr [BX].D_Ptr,0    ;Index pointer must be zero
  108.     Jne    NotLBR
  109.  
  110.     Mov    CX,11            ;Check name of blanks
  111.     Lea    SI,Byte Ptr [BX].D_File
  112.     Mov    DI,Offset Blanks
  113.     Rep    Cmpsb
  114.     Je    Load2
  115.  
  116.     Mov    CX,11            ;May be ********DIR name
  117.     Lea    SI,Byte Ptr [BX].D_File
  118.     Mov    DI,Offset DirKey
  119.     Rep    Cmpsb
  120.     Jne    NotLBR
  121.     Mov    CL,0            ; Indicate LUPC format
  122.     Jmp    Short Load3
  123.  
  124. NotLBR: Mov    DX,Offset Msg6        ; Say not valid format
  125.     Jmp    Errors
  126.  
  127. Load2:    Mov    CL,1            ; Indicate CP/M format in use
  128.     Sub    AX,AX
  129.     Mov    Word Ptr [BX].D_CRC,AX
  130.     Cmp    Word Ptr [BX].D_Cdate,AX
  131.     Jne    Load3            ; or original LU format
  132.     Mov    CL,2
  133.  
  134. Load3:    Mov    Mode,CL         ; Set library format type
  135. Load4:    Mov    AX,Word Ptr [BX].D_Len    ; Number of dir sectors
  136.     Add    AX,AX            ;  to num entries
  137.     Add    AX,AX
  138.     Dec    AL            ; less master entry
  139.     Mov    NumDir,AX
  140.     Mov    CL,5            ; Get size of directory
  141.     Shl    AX,CL            ;  in bytes
  142.  
  143.     Mov    CX,AX            ; Remaining direc size
  144.     Mov    DX,DirPtr        ; Load rest of directory
  145.     Call    ReadLb
  146.     Ret
  147. LoadDir Endp
  148.  
  149.     Page
  150. ;
  151. ;    Search for requested file
  152.  
  153. Search    Proc    Near            ; Name is in "MEMBER"
  154.  
  155.     Mov    DX,Offset MyDTA     ; Establish data xfer area
  156.     Mov    AH,1Ah
  157.     Int    21h
  158.  
  159.     Call    OpnIn            ; Get first file
  160.     Jz    Srch3            ; no more files?
  161.     Mov    DX,Offset Version    ; member name(s) missing
  162.     Jmp    Error
  163.  
  164. Srch3:    Mov    BX,DirPtr        ; First DIR entry
  165.     Mov    DX,NumDir
  166.  
  167. Srch5:    Cmp    Byte Ptr [BX].D_Stat,Active
  168.     Jne    Srch7            ; entry not active
  169.  
  170.     Lea    DI,Byte Ptr [BX].D_File
  171.     Mov    SI,Offset Member    ; Selected member name
  172.     Mov    CX,11
  173.     Rep    Cmpsb            ; found member
  174.     Je    Srch8
  175.  
  176. Srch7:    Add    BX,Dir_Len        ; next entry
  177.     Dec    DX
  178.     Jnz    Srch5
  179.  
  180.     Call    Add            ; Not found, add it
  181.     Jmp    Short Srch9
  182.  
  183. Srch8:    Call    Replace         ; Matched, replace it
  184.  
  185. Srch9:    Call    OpenNxt         ; Get next matching file name
  186.     Jz    Srch3
  187.     Ret
  188. Search    Endp
  189.     Page
  190. ;
  191. ;    Determine the name of the next input file and open it
  192.  
  193. OpnIn    Proc    Near
  194.     Push    BX
  195.  
  196. OpenIt1:Call    GetNext         ; Get next member operand,
  197.     Jnz    OpenIt            ; set ZF if no more names
  198.     Inc    SI
  199.     Jmp    OpnIn9
  200.  
  201. OpenIt: Mov    AH,4Eh            ; Find first matching entry
  202.     Mov    DX,Offset FileNm
  203.     Sub    CX,CX
  204.     Int    21h
  205.     Jc    Err9            ; member not found
  206.     Jmp    OpnIn1
  207.  
  208. OpenNxt:Push    BX            ; get next file
  209. OpnIn0: Mov    AH,4Fh
  210.     Int    21h
  211.     Jc    OpenIt1
  212.     Or    AL,AL            ; Any found?
  213.     Jnz    OpenIt1         ; no, try next operand
  214.  
  215. OpnIn1: Or    AL,AL            ; Any found?
  216.     Jnz    OpnIn9            ; no, ZF=0
  217.  
  218.     Mov    SI,Offset MyDTA+30    ; Copy found name
  219.     Mov    BX,FilePtr        ;  in ASCIIZ format
  220.     Mov    DI,Offset Member    ;  and FCB format
  221.     Mov    CX,13
  222. OpnIn2: Lodsb
  223.     Cmp    AL,0            ; End of name?
  224.     Je    OpnIn5
  225.     Mov    Byte Ptr [BX],AL
  226.     Inc    BX
  227.     Cmp    AL,'.'                  ; Start of extension?
  228.     Je    OpnIn3
  229.     Stosb
  230.     Jmp    Short OpnIn4
  231.  
  232. OpnIn3: Mov    AL,' '                  ;  yes, pad fname with blanks
  233.     Rep    Stosb
  234.     Mov    DI,Offset Ext        ;  yes, point to ext
  235.     Mov    CL,4
  236. OpnIn4: Loop    OpnIn2
  237.     Jcxz    OpnIn7
  238. OpnIn5: Mov    AL,' '                  ; Pad FCB ext with blanks
  239.     Rep    Stosb
  240. OpnIn7: Mov    DI,BX            ; Append ASCIIZ stopper
  241.     Mov    AX,0FF00h        ;  to input file name
  242.     Stosw
  243.  
  244.     Cmp    Word Ptr Ext,'BL'       ; Don't allow LBR as member
  245.     Jne    OpnIn6
  246.     Cmp    Byte Ptr Ext+2,'R'
  247.     Jne    OpnIn6
  248.     Jmp    OpnIn0
  249.  
  250. OpnIn6: Mov    AX,3D00h        ; Open member file for reading
  251.     Mov    DX,Offset FileNm
  252.     Int    21h
  253.     Mov    IHandle,AX
  254.     Jnc    OpnIn8
  255. Err9:    Mov    DX,Offset Msg9        ; Open failed
  256.     Call    PrintS
  257.     Mov    DX,Offset FileNm
  258.     Jmp    Error
  259.  
  260. OpnIn8: Sub    AX,AX            ; Indicate file open
  261. OpnIn9: Pop    BX
  262.     Ret
  263. OpnIn    Endp
  264.  
  265. ;
  266. ;    Get free directory entry
  267.  
  268. GetDir    Proc    Near            ; Returns BX
  269.     Mov    BX,DirPtr        ; First dir entry
  270.     Mov    DX,NumDir        ; Number of entries
  271. GetDir1:
  272.     Cmp    Byte Ptr [BX].D_Stat,Unused
  273.     Je    GetDir4         ; not active or deleted
  274.  
  275.     Add    BX,Dir_Len        ; Next directory entry
  276.     Dec    DX            ; Number of dir entries
  277.     Jnz    GetDir1         ; more, try next entry
  278.     Cmp    DX,BX            ; Indicate no free entries
  279. GetDir4:Ret
  280. GetDir    Endp
  281.     Page
  282. ;
  283. ;    Replace the requested file
  284.  
  285. Replace Proc    Near            ; BX points to directory entry
  286.     Mov    Action,'R'
  287.     Call    GetSize         ; Get member file sectors
  288.  
  289.     Cmp    Word Ptr [BX].D_Len,AX    ; Same size or smaller?
  290.     Jae    Rep0            ;  yes, in place
  291.     Push    AX            ; Save number of sectors
  292.     Push    BX            ;  and original dir entry
  293.     Call    GetDir            ; See if last used member
  294.     Mov    CX,BX
  295.     Pop    BX
  296.     Sub    CX,Dir_Len
  297.     Cmp    BX,CX            ; last one?
  298.     Pop    AX            ; Get sectors back
  299.     Jne    Rep1            ;  no, add to end
  300.  
  301. Rep0:    Mov    Word Ptr [BX].D_Len,AX    ; Change size
  302.  
  303.     Call    RepDir            ; Replace directory entry
  304.  
  305.     Mov    AX,Word Ptr [BX].D_Ptr    ; Get location
  306.     Sub    DX,DX
  307.     Mul    C128            ; into bytes
  308.     Xchg    DX,AX
  309.     Mov    CX,AX
  310.  
  311.     Mov    AL,0
  312.     Call    Lseek1            ; Point to original member
  313.  
  314.     Mov    DX,Offset MsgR        ; Say REPLACING
  315.     Call    PrintS
  316.     Mov    DX,Offset FileNm
  317.     Call    PrintS
  318.     Jmp    Add2            ; Copy the replacement file
  319.  
  320. Rep1:    Mov    Byte Ptr [BX].D_Stat,Unused ; Mark original as free
  321.     Call    RepDir            ; Replace directory entry
  322.     Mov    DX,Offset MsgU        ; Say UPDATING
  323.     Jmp    Short Addit
  324.  
  325. RepDir:
  326.     Call    GetDate         ; Get Create stamp
  327. RepDir1:
  328.     Push    AX            ; Re-write a directory entry
  329.     Push    BX
  330.     Push    CX
  331.     Push    DX
  332.  
  333.     Mov    DX,BX            ; Reposition library
  334.     Sub    DX,MstPtr        ;  to dir entry
  335.     Mov    AL,0
  336.     Call    Lseek0
  337.     Call    WriteL            ; Rewrite entry
  338.     Mov    Updated,255
  339.  
  340.     Pop    DX
  341.     Pop    CX
  342.     Pop    BX
  343.     Pop    AX
  344.     Ret
  345.     Page
  346. ;
  347. ;    Add new member to end of library
  348.  
  349. Add:    Mov    DX,Offset MsgA        ; Say ADDING
  350.     Mov    Action,'A'
  351. Addit:    Call    PrintS
  352.     Mov    DX,Offset FileNm
  353.     Call    PrintS
  354.  
  355.     Call    GetDir            ; Get free dir entry
  356.     Jz    Add1
  357.     Mov    DX,Offset Msg5        ; No free entries
  358.     Jmp    Error
  359.  
  360. Add1:    Mov    SI,Offset Member    ; Place name in dir
  361.     Lea    DI,Byte Ptr [BX].D_File
  362.     Mov    CX,11
  363.     Rep    Movsb
  364.  
  365.     Sub    DX,DX            ; Pos lbr to EOF
  366.     Call    Lseek
  367.     Add    AX,127            ; Round up size
  368.     Adc    DX,0
  369.     Div    C128            ;  make into sector
  370.     Mov    Word Ptr [BX].D_Ptr,AX
  371.  
  372.     Call    GetSize         ; Get member file sectors
  373.     Mov    Word Ptr [BX].D_Len,AX
  374.  
  375. Add2:    Mov    AL,0            ; Position member to start
  376.     Call    Iseek0
  377.  
  378. Add3:    Mov    CX,BufLen        ; Buffer size
  379.     Call    Read            ; Read a block
  380.     Jc    Add7
  381.  
  382.     Mov    AX,ReadSiz        ; Bytes to write
  383.     Add    AX,127            ;  rounded up
  384.     Mov    CL,7
  385.     Shr    AX,CL
  386.     Shl    AX,CL
  387.     Mov    CX,AX
  388.     Call    Write            ; Write a block
  389.  
  390.     Jmp    Short Add3
  391.  
  392. Add7:    Mov    Byte Ptr [BX].D_Stat,0    ; Mark active
  393.  
  394.     Call    RepDir            ; Replace directory entry
  395.  
  396.     Mov    BX,IHandle        ; Close input
  397.     Call    Close
  398.     Ret
  399. Replace Endp
  400.  
  401.     Subttl    --- Read/Write routines
  402.     Page
  403. ;
  404. ;    Read a directory entry
  405.  
  406. R_W    Proc    Near
  407. ReadLib:Mov    CX,Dir_Len        ; Read a block, length in CX
  408. ReadLb: Mov    BX,LHandle        ; DX points to buffer
  409.     Mov    AH,3Fh
  410.     Int    21h
  411.     Jnc    Readl0            ; Read okay?
  412.     Jmp    Err2            ;  no, say I/O error
  413.  
  414. Readl0: Or    AX,AX            ; Any data read?
  415.     Jnz    Readl9
  416.     Jmp    NotLBR            ; EOF unexpected, invalid LBR
  417. Readl9: Ret
  418.  
  419. ;    Read Blocks Subroutine
  420.  
  421. Read:    Push    BX            ; Read next block, length in CX
  422.     Mov    BX,IHandle        ; File handle
  423.     Mov    DX,BufPtr
  424.     Mov    AH,3Fh            ; Read from file
  425.     Int    21h
  426.     Jc    Err2
  427.     Or    AX,AX            ;Any data read?
  428.     Jnz    Read2            ; no, send message
  429.     Stc
  430.     Jmp    Short Rexit
  431.  
  432. Read2:    Mov    ReadSiz,AX        ;Save size read
  433.     Sub    CX,AX            ; bytes not read
  434.     Jz    Rexit
  435.     Mov    DI,AX
  436.     Add    DI,BufPtr        ; byte after read data
  437.     Mov    AL,1Ah            ; pad with EOF (1A)
  438.     Rep    Stosb
  439. Rexit:    Pop    BX
  440.     Ret
  441.  
  442. Err2:    Mov    DX,Offset Msg2        ;Say I/O error reading
  443.     Jmp    Error
  444.     Page
  445. ;
  446. ;    Write a Sector Subroutine
  447.  
  448. Write:    Push    BX            ; Write a sector, length in CX
  449.     Push    DX
  450.     Mov    DX,BufPtr
  451. Write1: Mov    AH,40h            ; Write to a file
  452.     Mov    BX,LHandle        ; File handle
  453.     Int    21h
  454.     Jc    Err3
  455.     Cmp    AX,CX            ; Wrote it?
  456.     Jne    Err4            ;  no, full
  457.     Pop    DX
  458.     Jmp    Short Rexit
  459.  
  460. WriteD: Mov    CX,DirLen        ; Re-write entire directory
  461.     Jmp    Short Write2
  462.  
  463. WriteL: Mov    CX,Dir_Len        ; Re-write one dir entry
  464. Write2: Push    BX
  465.     Push    DX
  466.     Mov    DX,BX
  467.     Jmp    Short Write1
  468.  
  469. Err3:    Mov    DX,Offset Msg3        ; Say I/O error writing
  470.     Jmp    Error
  471. Err4:    Mov    DX,Offset Msg4        ; Say DISK FULL
  472.     Jmp    Error
  473. R_W    Endp
  474.  
  475.     Subttl    --- Open or Create Library
  476.     Page
  477. ;
  478. ;    Open Library Subroutine
  479.  
  480. OpenLbr Proc    Near            ; Open the library
  481.     Mov    DX,Offset LbrName    ; LBR file name
  482.     Mov    AX,3D02h        ; Open LBR file for updating
  483.     Int    21h
  484.     Jc    Err1            ; Open okay?
  485.     Mov    LHandle,AX        ;  yes, save handle
  486.     Ret
  487.  
  488. Err1:    Cmp    AL,3            ; Was it found
  489.     Ja    Err7
  490.     Call    Create            ;  no, make new one
  491.     Jmp    OpenLbr
  492.  
  493. Err7:    Mov    DX,Offset Msg7        ; Say open failed
  494. Errors: Call    PrintS
  495.     Mov    DX,Offset LbrName
  496.     Jmp    Error
  497. OpenLbr Endp
  498.  
  499.  
  500.  
  501. ;    Create Library Subroutine
  502.  
  503. Create    Proc    Near            ;Create output file
  504.  
  505. Creat0: Mov    DX,Offset AskDir    ;Get number of entries
  506.     Call    PrintS
  507.     Mov    AH,0Ah            ;Read kybd buffer
  508.     Mov    DX,Offset Reply
  509.     Int    21h
  510.     Mov    CL,Reply+1        ;Get reply length
  511.     Sub    CH,CH
  512.     Mov    SI,Offset Reply+2
  513.     Call    ASC2BIN         ; and make it numeric
  514.     Jc    Creat2
  515.     Cmp    AX,MaxDir        ; want over 256
  516.     Ja    Creat0
  517.     Mov    NumDir,AX
  518.     Or    AX,AX            ; zero to quit?
  519.     Jnz    Creat1
  520.     Jmp    Done
  521.  
  522. Creat1: Sub    CX,CX            ;Normal attribute
  523.     Mov    DX,Offset LbrName    ;New file name
  524.     Mov    AH,3Ch            ;Create a file
  525.     Int    21h
  526.     Jnc    Creat2
  527.     Mov    DX,Offset Msg8        ;Say CREATE failed
  528.     Jmp    Error
  529.  
  530. Creat2: Mov    LHandle,AX        ;Save file handle
  531.     Mov    AX,NumDir
  532.     Add    AX,4            ;Round up including master
  533.     And    AX,01FCh        ; in fours
  534.     Mov    NumDir,AX
  535.     Mov    DX,AX
  536.     Mov    CL,5            ;Get size of directory
  537.     Shl    DX,CL            ; in bytes
  538.     Mov    DirLen,DX
  539.     Dec    NumDir            ; actual entries
  540.     Mov    CL,2            ; into sectors
  541.     Shr    AX,CL
  542.     Mov    BP,AX            ; save dir count
  543.     Page
  544. ;
  545. ;    Clear the new directory entries
  546.  
  547.     Mov    BX,MstPtr        ; First member entry
  548.     Mov    DX,NumDir
  549.     Inc    DX            ; Include master entry
  550.     Sub    AL,AL
  551. Creat4: Mov    CX,Dir_Len
  552.     Mov    DI,BX
  553.     Rep    Stosb
  554.     Mov    Byte Ptr [BX].D_Stat,Unused
  555.     Add    BX,Dir_Len
  556.     Dec    DX
  557.     Jnz    Creat4
  558.  
  559. ;    Initialize newly created library
  560.  
  561. Creat5: Mov    BX,MstPtr        ; Initalize master entry
  562.     Mov    Word Ptr [BX].D_Len,BP    ; Number of DIR sectors
  563.     Mov    Byte Ptr [BX].D_Stat,Active
  564.  
  565.     Mov    SI,Offset Blanks    ; Master member name
  566.     Lea    DI,Word Ptr [BX].D_File ;  is all blank
  567.     Mov    CX,11
  568.     Rep    Movsb
  569.  
  570.     Call    LibDate         ; Get LBR create date/time
  571.  
  572.     Mov    BX,MstPtr        ; Format create date/time
  573.     Call    GetDat2
  574.  
  575. Creat6: Mov    CX,DirLen        ;Write all entries
  576.     Mov    BX,MstPtr        ; starting with master dir
  577.     Call    WriteD
  578.     Mov    Updated,0
  579.  
  580. ;    Close the library
  581.  
  582. CloseLbr:
  583.     Cmp    Mode,1            ; Is it LU86 format?
  584.     Jne    CloseL            ;  no, leave master entry alone
  585.     Cmp    Updated,0        ; Any updates?
  586.     Je    CloseL            ;  no, skip it
  587.     Call    LibDate         ; Get LBR update date/time
  588.  
  589.     Mov    BX,MstPtr        ; Format update date/time
  590.     Mov    Action,'R'              ;  in master dir entry
  591.     Call    CPM_Dat         ; Get CP/M date
  592.     Call    RepDir1         ; Replace master dir entry
  593.  
  594. CloseL: Mov    BX,LHandle
  595. Close:    Mov    AH,3Eh            ; DOS close handle
  596.     Int    21h
  597.     Ret
  598. Create    Endp
  599.  
  600.  
  601.     Subttl    '--- Format original file datestamp'
  602.     Page
  603. ;
  604. ;    Put original file date/time into directory entry
  605.  
  606. GetDate Proc    Near            ;Determine original date
  607.     Cmp    Mode,2            ; Date stamps supported?
  608.     Jne    GetDat1         ; no, leave as zeros
  609.     Ret
  610.  
  611. GetDat1:
  612.     Call    FilDate         ; Get DOS file date
  613. GetDat2:
  614.     Cmp    Mode,0            ; Is it LUPC format?
  615.     Jne    GetDat3         ; no, must be CP/M
  616.     Call    SetDate         ; yes, set ASCII stamps
  617.     Ret
  618. GetDat3:                ; Stamps are CP/M format
  619.     Call    CPM_Dat         ; Get days in AX, time in CX
  620.     Ret
  621. GetDate Endp
  622.  
  623.  
  624. FilDate Proc    Near            ; Return DOS file date
  625.     Push    BX
  626.     Mov    BX,IHandle
  627.     Mov    AX,5700h        ; Get input file date/time
  628.     Int    21h            ;  in DX:CX
  629.     Pop    BX
  630.     Ret
  631. FilDate Endp
  632.  
  633.  
  634. LibDate Proc    Near
  635.     Mov    BX,LHandle        ; Get LBR create date/time
  636.     Mov    AX,5700h        ;  in DX:CX
  637.     Int    21h
  638.     Ret
  639. LibDate Endp
  640.  
  641.     Subttl    '--- Convert date to CP/M format'
  642.     Page
  643. CPM_Dat Proc    Near
  644. ;    Push    BX            ; BX points to dir entry
  645.     Push    CX            ; CX contains file time
  646. ;    Push    DX            ; DX contains DOS-file year
  647. ;    Push    AX            ; AX returns CP/M days
  648.  
  649.     Mov    [BX].D_CRC,0        ; No CRC value yet
  650.  
  651. ;    Convert DOS-file date to mm/dd/yy values
  652.  
  653.     Mov    SI,DX            ; Get month part
  654.     And    SI,Mask Mo
  655.     Mov    CL,Mo
  656.     Shr    SI,CL
  657.  
  658.     Mov    BP,DX            ; Get day part
  659.     And    BP,Mask Dy
  660.  
  661.     Mov    DI,DX            ; Get year part
  662.     And    DI,Mask Yr
  663.     Mov    CL,Yr
  664.     Shr    DI,CL
  665. ;    Add    DI,80            ; IBM PC DOS base year
  666.  
  667. ;    Get number of days since Jan 1, 1978
  668.  
  669.     Cmp    SI,2            ; If Month > 2 Then
  670.     Jbe    Cd1
  671.     Sub    SI,3            ;      Month=Month-3
  672.     Add    DI,4            ;      Year=Year-76
  673.     Jmp    Short Cd2
  674.  
  675. Cd1:    Add    SI,9            ; Else Month=Month+9
  676.     Add    DI,3            ;      Year=Year-77
  677.  
  678. Cd2:    Mov    AX,DI            ; Leaps = (1461*Year)\4
  679.     Sub    DX,DX
  680.     Imul    C1461
  681.     Shr    AX,1
  682.     Shr    AX,1
  683.     Mov    CX,AX
  684.  
  685. Cd3:    Mov    AX,SI            ; Days = (153*Month)/5
  686.     Sub    DX,DX
  687.     Imul    C153
  688.     Sub    DX,DX
  689.     Add    AX,4
  690.     Idiv    C5
  691.     Add    AX,CX            ; C_Date = Day-671+Leaps+Days
  692.     Add    AX,BP
  693.     Sub    AX,671
  694.  
  695. Cd4:    Pop    CX            ; Recover time
  696.     Cmp    Action,'A'              ; Adding or replacing?
  697.     Je    Cd5
  698.     Mov    [BX].D_Udate,AX     ; Set update stamps
  699.     Mov    [BX].D_Utime,CX
  700.     Ret
  701.  
  702. Cd5:    Mov    [BX].D_Cdate,AX     ; Set create stamps
  703.     Mov    [BX].D_Ctime,CX
  704.     Ret
  705.  
  706. C1461    Dw    1461            ; Days in 4-years
  707. C5    Dw    5            ; Average days per month
  708. C153    Dw    153
  709. CPM_Dat Endp
  710.  
  711.     Subttl    '--- Convert date/time to ASCII (LUPC) format'
  712.     Page
  713. SetDate Proc    Near            ;Place ASCII date/time in entry
  714.     Push    CX            ; save time
  715.     Lea    DI,Byte Ptr [BX].D_CRC    ; Target for formatted date    file date
  716.  
  717.     Mov    AX,DX            ; Get month part
  718.     And    AX,Mask Mo
  719.     Mov    CL,Mo
  720.     Call    Format
  721.     Mov    AL,'/'
  722.     Stosb                ; Add delimiter
  723.  
  724.     Mov    AX,DX            ; Get day part
  725.     And    AX,Mask Dy
  726.     Call    Format1
  727.     Mov    AL,'/'
  728.     Stosb                ; Add delimiter
  729.  
  730.     Mov    AX,DX            ; Get year part
  731.     And    AX,Mask Yr
  732.     Mov    CL,Yr
  733.     Add    AX,80*512        ; Base date 1980
  734.     Call    Format
  735.  
  736.     Pop    DX            ; Recover file time
  737.     Lea    DI,Byte Ptr [BX].D_Utime
  738.  
  739.     Mov    AX,DX            ; hours part
  740.     And    AX,Mask Hh
  741.     Mov    CL,Hh
  742.     Call    Format
  743.     Mov    AL,':'
  744.     Stosb                ; add delimiter
  745.  
  746.     Mov    AX,DX            ; minutes part
  747.     And    AX,Mask Mm
  748.     Mov    CL,Mm
  749.     Call    Format
  750.     Mov    AL,':'
  751.     Stosb                ; add delimiter
  752.  
  753.     Mov    AX,DX            ; seconds part
  754.     And    AX,Mask Xx
  755.     Add    AX,AX
  756.     Call    Format1
  757.     Ret
  758.  
  759. Format: Shr    AX,CL            ;Convert binary to ASCII
  760. Format1:Aam
  761.     Or    AX,'00'
  762.     Xchg    AH,AL
  763.     Stosw
  764.     Ret
  765. SetDate Endp
  766.  
  767.     Subttl    ---  Subroutines
  768.     Page
  769. GetSize Proc    Near
  770.     Call    Iseek            ; Seek to EOF to get size
  771.     Push    AX
  772.     Shl    AL,1            ; Get bytes in last sector
  773.     Shr    AL,1
  774.     Sub    AH,AH
  775.     Cmp    AL,0            ; Full sector?
  776.     Je    GetSz1            ;  yup, no pad bytes
  777.     Mov    AH,128
  778.     Sub    AH,AL
  779. GetSz1: Mov    Byte Ptr [BX].D_Pad,AH
  780.     Pop    AX
  781.  
  782.     Add    AX,127            ; Round up size to sectors
  783.     Adc    DX,0
  784.     Div    C128
  785.     Ret
  786. GetSize Endp
  787.  
  788. Lseek    Proc    Near            ;Reposition library
  789.     Mov    AL,02h            ; to EOF
  790. Lseek0: Sub    CX,CX            ; to offset in DX:CX
  791. Lseek1: Push    BX
  792.     Mov    BX,LHandle
  793.     Jmp    Short Iseek1
  794.  
  795. Iseek:    Mov    AL,02h            ; Reposition to EOF
  796. Iseek0: Sub    CX,CX            ;  or to beginning
  797.     Sub    DX,DX
  798.     Push    BX
  799.     Mov    BX,IHandle
  800. Iseek1: Mov    AH,42h            ; DOS Lseek disk
  801.     Int    21h
  802.     Pop    BX
  803.     Ret
  804. Lseek    Endp
  805.  
  806. ;    Print String - Display a message
  807.  
  808. PrintS    Proc    Near            ;Print string like Int 21h (9)
  809.     Push    BX            ;DX points to string
  810.     Push    SI
  811.     Mov    SI,DX
  812. PS1:    Lodsb
  813.     Cmp    AL,0            ;Skip zeros
  814.     Je    PS1
  815.     Cmp    AL,255            ;String ends in a hex FF
  816.     Je    PS9            ; so can print $
  817.     Mov    AH,14            ;Use TTY write
  818.     Mov    BX,7
  819.     Int    10h
  820.     Jmp    PS1
  821.  
  822. PS9:    Pop    SI
  823.     Pop    BX
  824.     Ret
  825. PrintS    Endp
  826.     Page
  827. ;
  828. ;    Convert an ASCII string to a binary value
  829.  
  830. ASC2BIN Proc    Near            ;ASCII numbers to binary in AX
  831.     Push    DI            ; DS:SI has pointer to string
  832.     Push    DX            ; CX has length of string
  833.  
  834.     Sub    DI,DI            ; Zero result
  835.     Sub    DX,DX            ; Clear for multiplies
  836. Cnvrt1: Lodsb
  837.     Cmp    AL,'0'                  ; valid digit?
  838.     Jb    Cnvrt2
  839.     Cmp    AL,'9'
  840.     Ja    Cnvrt2
  841.     Sub    AL,'0'                  ; digit to binary
  842.     Cbw
  843.     Add    DI,AX
  844.     Dec    CX
  845.     Jz    Cnvrt3
  846.     Mov    AX,DI
  847.     Mul    Ten
  848.     Mov    DI,AX
  849.     Jmp    Cnvrt1
  850.  
  851. Cnvrt2: Stc                ; Invalid arg
  852.     Jmp    Short Cnvrt4
  853.  
  854. Cnvrt3: Mov    AX,DI            ;Save result
  855.     Clc
  856. Cnvrt4: Pop    DX
  857.     Pop    DI
  858.     Ret
  859. ASC2BIN Endp
  860.     Page
  861. ;
  862. ;    Allocate memory for buffers
  863.  
  864. Alloc    Proc    Near
  865.  
  866.     Mov    AH,30h            ; Get DOS version
  867.     Int    21h
  868.     Cmp    AL,2            ; Insure 2.0 or later
  869.     Jae    Alloc0
  870.     Mov    DX,Offset Sorry
  871.     Jmp    Error
  872.  
  873. Alloc0: Mov    BX,SP            ; Use memory from end of program
  874.     Mov    AX,Offset PgmEnd    ; to beginning of stack for buffers
  875.     Sub    BX,AX            ; with this many bytes available
  876.     Sub    BX,512            ; less a stack size
  877.     Cmp    BX,BufSize+DirSize+256
  878.     Jb    Alloc1            ; if not enough
  879.  
  880.     Mov    MstPtr,AX        ; Assign master directory entry
  881.     Add    AX,Dir_Len
  882.     Sub    BX,Dir_Len
  883.  
  884.     Mov    DirPtr,AX        ; Assign directory buffer
  885.     Add    AX,DirSize-Dir_Len    ; Bump to I/O buffer
  886.     Sub    BX,DirSize-Dir_Len
  887.  
  888.     Mov    BufPtr,AX        ; Assign I/O buffer
  889.     Mov    CL,7            ; Round up to 128-byte sector
  890.     Shr    BX,CL
  891.     Shl    BX,CL
  892.     Mov    BufLen,BX        ; and use what's left for it
  893.     Ret
  894.  
  895. Alloc1: Mov    DX,Offset Msg1        ; Say 'Not enough memory'
  896.     Jmp    Error
  897. Alloc    Endp
  898.     Page
  899. ;
  900. ;    Get Command Tail Operands
  901. ;
  902. ;    Input:    DS must point to program PSP
  903. ;    Output:
  904. ;        Carry flag if any errors encountered, message sent
  905. ;        LbrName - receives the first operand, library file name
  906. ;        FileNm    - receives the second operand, a member name
  907. ;        FilePtr - points to the first member name
  908.  
  909. GetParm Proc    Near            ; First operand is LBR name
  910.     Mov    SI,82h            ; Second is requested member
  911.     Sub    CX,CX
  912.     Or    CL,DS:[80h]        ; Length of command operands
  913.     Jnz    Parm0
  914.  
  915. Parm_Error:                ; Library name missing
  916.     Mov    DX,Offset Version    ;  or member name(s) missing
  917.     Jmp    Error            ;  so send usage message
  918.  
  919. Parm0:    Mov    DI,Offset ParmFld    ; Save command operands
  920.     Rep    Movsb
  921.     Mov    AL,CR
  922.     Stosb
  923.     Mov    SI,Offset ParmFld
  924.     Mov    CL,DS:[80h]
  925.  
  926. Parm1:    Lodsb                ; Skip leading blanks
  927.     Cmp    AL,' '                  ;  while finding LBR name
  928.     Loope    Parm1
  929.  
  930.     Mov    DI,Offset LbrName    ; Copy library name operand
  931. Parm2:    Stosb
  932.     Lodsb
  933.     Cmp    AL,0Dh            ; The library name operand may end
  934.     Je    Parm_Error        ; in a blank but not a CR, because
  935.     Cmp    AL,'.'                  ; a CR means there are no filenames
  936.     Je    Parm2a
  937.     Cmp    AL,' '                  ; Copy the first operand and check for
  938.     Loopne    Parm2            ; an extension delimiter.
  939.  
  940. ;    Add default LBR extension
  941.  
  942.     Jcxz    Parm_Error        ; If no member list
  943.     Mov    AX,'L.'                 ; If no extension is supplied,
  944.     Stosw                ; supply a default of .LBR
  945.     Mov    AX,'RB'
  946.     Stosw
  947.     Jmp    Short Parm2d
  948.  
  949. ;    Copy the library name extension
  950.  
  951. Parm2a: Stosb
  952.     Lodsb
  953.     Cmp    AL,0Dh
  954.     Je    Parm_Error
  955.     Cmp    AL,' '
  956.     Loopne    Parm2a
  957.  
  958. Parm2d: Mov    AX,0FF00h        ; Append ASCIIZ and print stopper
  959.     Stosw
  960.     Mov    ParmNxt,SI        ; Set pointer to next operand
  961.     Clc
  962.     Ret
  963.     Page
  964. ;
  965. ;    Get pointer to next command operand
  966.  
  967. GetNext:                ; Returns ZF if there's an operand
  968.     Mov    DI,Offset FileNm    ; Copy the next operand as a
  969.     Mov    SI,ParmNxt        ; member file name
  970. Parm3a: Lodsb
  971.     Cmp    AL,' '                  ; Skip leading blanks
  972.     Loope    Parm3a
  973.     Dec    SI
  974. Parm3:    Lodsb
  975.     Mov    ParmNxt,SI
  976.     Cmp    AL,' '                  ; Multiple member names are separated
  977.     Je    Parm4            ; by blanks. The last one ends in a CR.
  978.     Cmp    AL,CR
  979.     Je    Parm4
  980.     Stosb
  981.     Jmp    Short Parm3
  982.  
  983. Parm4:    Mov    AX,0FF00h        ; Append ASCIIZ and print stopper
  984.     Stosw
  985.  
  986. ;    Get pointer to file name part of member name operand
  987.  
  988.     Mov    SI,DI            ; Each member filename may include
  989.     Std                ; a drive and/or path names, need to
  990.     Dec    SI            ; the address of the filename part
  991. Parm5:    Lodsb
  992.     Cmp    AL,':'                  ; Check for drive
  993.     Je    Parm6
  994.     Cmp    AL,'\'                  ; Check for paths
  995.     Je    Parm6
  996.     Cmp    AL,'/'
  997.     Je    Parm6
  998.     Cmp    SI,Offset Filenm-1
  999.     Ja    Parm5
  1000.     Dec    SI
  1001. Parm6:    Inc    SI            ; Save a pointer to the filename
  1002.     Inc    SI
  1003. Parm7:    Mov    FilePtr,SI        ; part of the member name
  1004.     Cld
  1005.     Clc
  1006.     Cmp    Byte Ptr FileNm,0    ; Set ZF to indicate whether
  1007.     Ret                ; there is a file name
  1008.  
  1009. GetParm Endp
  1010.     Page
  1011. ;
  1012. ;    Error messages
  1013.  
  1014. Version Db    'LUU - Version 1.64 - V.Buerg',CR,LF
  1015. Msg0    Db    CR,LF,'Usage:  LUU library[.LBR] filename(s)',Stopper
  1016. Msg1    Db    CR,LF,'Not enough memory',255
  1017. Msg2    Db    CR,LF,'Read error',CR,LF,255
  1018. Msg3    Db    CR,LF,'Write error',CR,LF,255
  1019. Msg4    Db    CR,LF,'Disk full, last update incomplete',CR,LF,255
  1020. Msg5    Db    CR,LF,'Directory is full, no update',CR,LF,255
  1021. Msg6    Db    CR,LF,'Invalid LBR format: ',255
  1022. Msg7    Db    CR,LF,"Can't open library: ",255
  1023. Msg8    Db    CR,LF,'CREATE failed',CR,LF,255
  1024. Msg9    Db    CR,LF,'File not found  ',255
  1025.  
  1026. EofMsg    Db    CR,LF,'All done!',255
  1027. AskDir    Db    CR,LF,'How many directory entries? (3-255,0 to quit)  ',255
  1028.  
  1029. Sorry    Db    CR,LF,'Wrong DOS version',255
  1030.     Page
  1031. Reply    Db    4,0,'    '              ; Reply buffer
  1032.  
  1033. Updated Db    0            ; Non-zero if changes made
  1034.  
  1035. Mode    Db    1            ; Directory format:
  1036.                     ;  0 = IBM/PC, LUPC stamps
  1037.                     ;  1 = CP/M stamps
  1038.                     ;  2 = no stamps
  1039. Action    Db    'A'                     ; Transaction type: A or R
  1040.  
  1041. IHandle Dw    0            ; Input file handle
  1042. LHandle Dw    0            ; Library file handle
  1043.  
  1044. NumDir    Dw    0            ; Number of directory entries
  1045. DirLen    Dw    0            ; Length of dir in bytes
  1046.  
  1047. FilePtr Dw    0            ; Ptr to filename part
  1048. ParmNxt Dw    0            ; Pointer to next operand
  1049.  
  1050. MstPtr    Dw    0            ; Offset to master entry
  1051. DirPtr    Dw    0            ; Offset to directory
  1052. BufPtr    Dw    0            ; Offset to buffers
  1053. BufLen    Dw    0            ; Size of I/O buffer
  1054. ReadSiz Dw    0            ; Bytes read
  1055.  
  1056. Ten    Db    10            ; Some constants
  1057. C128    Dw    128
  1058. StkTop    Dw    0
  1059.  
  1060. Blanks    Db    13 Dup (' ')            ; Name in old format files
  1061. DirKey    Db    '********DIR'           ;  in new format libs
  1062.  
  1063. Member    Db    8 Dup (' ')             ; Requested member file
  1064. Ext    Db    3 Dup (' '),' ',255
  1065.  
  1066. MsgU    Db    CR,LF,'Updating   ',255 ; Cooking messages
  1067. MsgR    Db    CR,LF,'Replacing  ',255
  1068. MsgA    Db    CR,LF,'Adding     ',255
  1069.  
  1070. LbrName Equ    $
  1071. ParmFld Equ    LbrName+78        ; Member name operands
  1072. MyDTA    Equ    ParmFld+132        ; DTA for DOS
  1073. FileNm    Equ    MyDTA+128        ; Requested member files(s)
  1074.  
  1075. PgmEnd    Equ    FileNm+80        ; Last byte in program file
  1076. Luu    Endp
  1077.  
  1078. Cseg    Ends
  1079.     End    Luu
  1080.